package cn.yunyichina.provider.bed.thread;

import cn.yunyichina.provider.bed.dao.InpatientFeeDao;
import cn.yunyichina.provider.bed.dao.InpatientFeeListDao;
import cn.yunyichina.provider.bed.dao.InpatientFeeitemDao;
import cn.yunyichina.provider.bed.dao.InpatientFeeitemListDao;
import cn.yunyichina.provider.bed.entity.*;
import cn.yunyichina.provider.bed.vo.BedFeeResponseVo;
import cn.yunyichina.provider.bed.vo.BedVo;
import cn.yunyichina.provider.bed.vo.DailyBedFeeVoResponseVo;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.exception.CallException;
import cn.yunyichina.provider.iface.entity.base.Org;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.bed.BedFee;
import cn.yunyichina.provider.iface.entity.hisiface.bed.BedFeeDetail;
import cn.yunyichina.provider.iface.entity.hisiface.bed.DailyBedFeeVoResponse;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * 住院日清单保存线程处理
 * Created by admin on 2016/12/16.
 */
public class InpatientFeeSaveRunnable implements Callable<Response>{

    private BedVo bedVoRequest;

    private DailyBedFeeVoResponseVo dailyBedFeeVoResponse;

    private InpatientFeeDao inpatientFeeDao = SpringContextHandler.getBean(InpatientFeeDao.class);

    private InpatientFeeListDao inpatientFeeListDao = SpringContextHandler.getBean(InpatientFeeListDao.class);

    private InpatientFeeitemDao inpatientFeeitemDao = SpringContextHandler.getBean(InpatientFeeitemDao.class);

    private InpatientFeeitemListDao inpatientFeeitemListDao = SpringContextHandler.getBean(InpatientFeeitemListDao.class);

    private Logger logger = LoggerFactory.getLogger(InpatientFeeSaveRunnable.class);

    public InpatientFeeSaveRunnable(BedVo bedVo, DailyBedFeeVoResponseVo dailyBedFeeVoResponse){
        this.bedVoRequest = bedVo;
        this.dailyBedFeeVoResponse = dailyBedFeeVoResponse;
    }


    @Override
    public Response call() throws Exception {
        return save();
    }


    public Response save(){

        logger.info("【住院日清单保存线程处理】开始, 请求bedVo=" + JsonUtils.toJsonString(bedVoRequest) + ",dailyBedFeeVoResponse=" + JsonUtils.toJsonString(dailyBedFeeVoResponse));

        Response response = new Response();
        Map<String, String> map = new HashMap<>();

        try {
            saveInpatientFee(bedVoRequest, dailyBedFeeVoResponse);

        } catch (Exception e) {
            logger.error("【住院日清单保存线程处理】异常" , e);
        }

        return response;
    }

    /**
     * 保存住院日费用及明细
     * @param dailyBedFeeVoResponse
     */
    private void saveInpatientFee(BedVo bedVoRequest, DailyBedFeeVoResponseVo dailyBedFeeVoResponse){
        logger.info("【住院日清单保存线程处理-保存住院日费用】开始");
        String medicalCardId = bedVoRequest.getMedicalCardId();
        String hospitalCode = bedVoRequest.getHospitalCode();
        String costDate = bedVoRequest.getCostDate();//费用日期
        String inpatientId = bedVoRequest.getPatientId();//住院记录id
        String admissionNo = bedVoRequest.getAdmissionNo();//住院号
        Integer inTime = Integer.valueOf(bedVoRequest.getInTime());//住院次数

        MedicalCard medicalCard = null;
        if (StringUtils.isNotBlank(medicalCardId)){
            //查询绑定卡
            JSONObject medicalParam = new JSONObject();
            medicalParam.put("id", medicalCardId);
            logger.info("【住院日清单保存线程处理-查询绑定卡信息】, yyt.base.medicalcard.by.id.get request=" + JSON.toJSONString(medicalParam));
            Response medicalResponse = BaseService.callHumpFromInternal("yyt.base.medicalcard.by.id.get", JsonUtils.toJsonString(medicalParam));
            logger.info("【住院日清单保存线程处理-查询绑定卡信息】, yyt.base.medicalcard.by.id.get response=" + JSONObject.toJSONString(medicalResponse));
            if (!"0".equals(medicalResponse.getResultCode())) {
                throw new CallException("14010","找不到绑定卡信息 by id=" + medicalCardId);
            }
            medicalCard = JsonUtils.parseObject(medicalResponse.getResult(), MedicalCard.class);
        }


        // 查询组织信息-----------------------------------------------start
        Map<String, String> orgParamMap = new HashMap<String, String>();
        orgParamMap.put("org_code", hospitalCode);
        logger.info("【出入院-生成押金补缴订单-查询组织信息】, yyt.base.branchhospital.org.list request=" + JSON.toJSONString(orgParamMap));
        Response orgResponse = BaseService.callUnderlineFromInternal("yyt.base.branchhospital.org.list", JSON.toJSONString(orgParamMap));
        logger.info("【出入院-生成押金补缴订单-查询组织信息】, yyt.base.branchhospital.org.list response=" + JSONObject.toJSONString(orgResponse));
        if (!"0".equals(orgResponse.getResultCode())) {
            throw new CallException("14010","找不到机构信息 by org_code=" + hospitalCode);
        }
        List<Org> orgList = JsonUtils.parseArray(orgResponse.getResult(), Org.class);
        if (CollectionUtils.isEmpty(orgList)) {
            throw new CallException("14010","找不到机构信息 by org_code=" + hospitalCode);
        }
        Org org = orgList.get(0);

        //住院号不能为空
        if(StringUtils.isNotBlank(inpatientId)){
            /*Start-----入库-----Start*/
            List<InpatientFee> inpatientFees = new ArrayList<>();
            InpatientFee inpatientFeeVo = new InpatientFee();
            inpatientFeeVo.setInpatientId(inpatientId);
            inpatientFees = inpatientFeeDao.select(inpatientFeeVo);
            if(inpatientFees == null || inpatientFees.size() == 0){
                logger.info("【住院日清单保存线程处理-保存住院日费用】根据patientId查询住院日费用为空");
                InpatientFee inpatientFee = new InpatientFee();
                inpatientFee.setId(PKGenerator.generateId());
                inpatientFee.setOrgId(org.getId());
                inpatientFee.setOrgCode(org.getOrgCode());
                inpatientFee.setOrgName(org.getOrgName());
                inpatientFee.setBranchId("");
                inpatientFee.setBranchCode("");
                inpatientFee.setBranchName("");
                inpatientFee.setPatId(medicalCard==null?"":medicalCard.getPatId());
                inpatientFee.setPatName(medicalCard==null?"":medicalCard.getPatName());
                inpatientFee.setInpatientId(inpatientId);
                inpatientFee.setAdmissionNo(admissionNo);
                inpatientFee.setInTime(inTime);
                inpatientFee.setCostDate(costDate);
                inpatientFee.setDeptName(dailyBedFeeVoResponse.getDeptName());
                inpatientFee.setBedNo(dailyBedFeeVoResponse.getBedNo());
                inpatientFee.setDescription(dailyBedFeeVoResponse.getDescription());
                inpatientFee.setBalance(Integer.valueOf(dailyBedFeeVoResponse.getBalance()));
                inpatientFee.setTodayAmount(Integer.valueOf(dailyBedFeeVoResponse.getTodayAmount()));
                //插入主表
                inpatientFeeDao.insert(inpatientFee);

                inpatientFeeVo = new InpatientFee();
                inpatientFeeVo.setId(inpatientFee.getId());
                inpatientFees = inpatientFeeDao.select(inpatientFeeVo);
                //主表入库成功
                if(inpatientFees != null || inpatientFees.size() > 0){
                    List<BedFeeResponseVo> bedFeeItems = dailyBedFeeVoResponse.getBedFeeItems();
                    for (BedFeeResponseVo bedFeeItem : bedFeeItems) {
                        InpatientFeeList inpatientFeeList = new InpatientFeeList();
                        inpatientFeeList.setId(PKGenerator.generateId());
                        inpatientFeeList.setInpatientFeeId(inpatientFee.getId());
                        inpatientFeeList.setCostName(bedFeeItem.getCostName());
                        inpatientFeeList.setCostType(Integer.valueOf(bedFeeItem.getCostType()));
                        inpatientFeeList.setCostAmount(Integer.valueOf(bedFeeItem.getCostAmount()));
                        //插入bed_inpatient_fee_list表
                        inpatientFeeListDao.insert(inpatientFeeList);

                        InpatientFeeitem inpatientFeeitem = new InpatientFeeitem();
                        inpatientFeeitem.setId(PKGenerator.generateId());
                        inpatientFeeitem.setOrgId(org.getId());
                        inpatientFeeitem.setOrgCode(org.getOrgCode());
                        inpatientFeeitem.setOrgName(org.getOrgName());
                        inpatientFeeitem.setBranchId("");
                        inpatientFeeitem.setBranchCode("");
                        inpatientFeeitem.setBranchName("");
                        inpatientFeeitem.setPatId(medicalCard==null?"":medicalCard.getPatId());
                        inpatientFeeitem.setPatName(medicalCard==null?"":medicalCard.getPatName());
                        inpatientFeeitem.setInpatientId(inpatientId);
                        inpatientFeeitem.setAdmissionNo(admissionNo);
                        inpatientFeeitem.setInTime(inTime);
                        inpatientFeeitem.setCostDate(costDate);
                        inpatientFeeitem.setCostType(Integer.valueOf(bedFeeItem.getCostType()));
                        //插入bed_inpatient_feeitem表
                        inpatientFeeitemDao.insert(inpatientFeeitem);

                        List<BedFeeDetail> bedFeeDetails = bedFeeItem.getBedFeeDetails();
                        for (BedFeeDetail bedFeeDetail : bedFeeDetails) {
                            InpatientFeeitemList inpatientFeeitemList = new InpatientFeeitemList();
                            inpatientFeeitemList.setId(PKGenerator.generateId());
                            inpatientFeeitemList.setInpatientFeeitemId(inpatientFeeitem.getId());
                            inpatientFeeitemList.setProjectName(bedFeeDetail.getProjectName());
                            inpatientFeeitemList.setSpec(bedFeeDetail.getSpec());
                            inpatientFeeitemList.setUnit(bedFeeDetail.getUnit());
                            String quantity = bedFeeDetail.getQuantity();
                            //quantity可能会返回有小数点的情况
                            if(quantity!=null &&quantity.contains(".") ){
                                inpatientFeeitemList.setQuantity(Integer.valueOf(quantity.substring(0,quantity.indexOf("."))));
                            }else {
                                inpatientFeeitemList.setQuantity(Integer.valueOf(quantity));
                            }

                            inpatientFeeitemList.setAmount(Integer.valueOf(bedFeeDetail.getAmount()));
                            //插入bed_inpatient_feeitem_list表
                            inpatientFeeitemListDao.insert(inpatientFeeitemList);
                        }
                    }
                }
            }
            /*End-----入库-----End*/
        }
    }
}
